/* virtual machine */

#include "bvm.h"

#include <string.h>

void initRE(RE* r){
	r->memory = bf_newvec(Mem_t, MAXMEMSIZE);
	r->mp = 0;
	memset(r->memory, 0, MAXMEMSIZE * sizeof(Mem_t));
}

void execute(Proto* p){
	int cp;		/* code pointer */
	RE re;
	RE* r = &re;
	initRE(r); 
	for(cp = 0; cp < p->codelen; cp++){
		opcode* code = &(p->code[cp]);
		switch(code->t){
			case MOV:{
				r->mp += code->extra;
				if(r->mp > MAXMEMSIZE) {
					r->mp %= MAXMEMSIZE;
				} else if (r->mp < 0) {
					r->mp = (MAXMEMSIZE + r->mp) % MAXMEMSIZE;
				}
				break;
			}
			case ADD:{
				r->memory[r->mp] += code->extra;
				break;
			}
			case SET:{
				r->memory[r->mp] = code->extra;
				break;
			}
			case INPUT:{
				if(code->extra){	/* char? */
					r->memory[r->mp] = getchar();
				}else{
					scanf("%d", &(r->memory[r->mp]));
				}
				break;
			}
			case OUTPUT:{
				if(code->extra){	/* char? */
					putchar(r->memory[r->mp]);
				}else{
					printf("%d", r->memory[r->mp]);
				}
				break;
			}
			case LOOP:{
				if(!r->memory[r->mp]){
					cp = code->extra;
				}
				break;
			}
			case END:{
				if(r->memory[r->mp]){
					cp = code->extra;
				}
				break;
			}
		}
	}
} 
